package com.shangxian.giveithome.service.impl;


import com.shangxian.giveithome.code.CommonCode;
import com.shangxian.giveithome.controller.ImgFeiServer;
import com.shangxian.giveithome.controller.UserFeiController;
import com.shangxian.giveithome.entity.*;
import com.shangxian.giveithome.exception.ExceptionUtils;
import com.shangxian.giveithome.mapper.ActivityFeiMapper;
import com.shangxian.giveithome.mapper.MechanismDataMapper;
import com.shangxian.giveithome.mapper.MechanismFeiMapper;
import com.shangxian.giveithome.mapper.VolunteerMapper;
import com.shangxian.giveithome.service.ActivityFeiService;
import com.shangxian.giveithome.service.MechanismFeiService;
import com.shangxian.giveithome.service.VolunteerService;
import com.shangxian.giveithome.utils.PageUtils;
import com.shangxian.giveithome.utils.RqUtils;
import com.shangxian.giveithome.utils.TaskTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.shangxian.giveithome.properties.MechanismProperties.RQUrl;


@Service
@Slf4j
public class MechanismFeiServiceImpl implements MechanismFeiService {

    @Resource
    private MechanismFeiMapper mechanismFeiMapper;

    @Resource
    private MechanismDataMapper mechanismDataMapper;

    @Resource
    private ActivityFeiMapper activityFeiMapper;

    @Autowired
    private ActivityFeiService activityFeiService;

    @Autowired
    private VolunteerService volunteerService;

    @Resource
    private UserFeiController userFeiController;

    @Resource
    private ImgFeiServer imgFeiServer;

    @Resource
    private VolunteerMapper volunteerMapper;

    @Resource
    private TaskTool taskTool;

    /**
     * 根据用户id查询管理机构信息
     *
     * @param id
     * @return
     */
    @Override
    public MechanismDetails queryByMe(Long id) {
        Mechanism mechanism = mechanismFeiMapper.queryByMe(id);
        if (mechanism == null) {
            return null;
        }
        Long mr_id = mechanism.getId();
        MechanismDetails mechanismDetails = new MechanismDetails();
        BeanUtils.copyProperties(mechanism, mechanismDetails);
        //查询机构数据
        MechanismData mechanismData = mechanismDataMapper.queryById(mechanism.getId());
        if (mechanismData == null) {
            mechanismDetails.setMechanismData(new MechanismData(mechanism.getId(), 0, 0, 0, 0, 0, 0));
            return mechanismDetails;
        }
        mechanismDetails.setMechanismData(mechanismData);
        if (mechanismData.getActivityNumber() > 0) {
            //查看活动记录 //按照活动是否开始排序
            mechanismDetails.setActivities(activityFeiService.queryByMechanismId(mr_id));
        }
        if (mechanismData.getVolunteerNumber() > 0) {
            //查看义工审核记录
            List<VolunteerExamine> volunteers = volunteerService.queryById(mr_id);
            mechanismDetails.setVolunteers(volunteers);
        }
        return mechanismDetails;

    }

    /**
     * 查询用户活动
     *
     * @param id
     * @param offSets
     * @param pageable
     * @return
     */
    @Override
    public PageableDetails queryUserActivity(Long id, Long offSets, Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        int offSet = Math.toIntExact(offSets);
        //总条数
        Integer count = activityFeiMapper.countUserActivityRelationship(id);
        if (count == 0) {
            return null;
        }
        //查询进行中且签到的所有数据
        List<ActiveRelationship> activeRelationships = activityFeiMapper.queryByUserActiveRelation1(id, pageNumber * pageSize, pageSize);
        if (CollectionUtils.isEmpty(activeRelationships) || activeRelationships.size() < 10) {
            int pageNums = 0;
            int pagesize = 0;
            //若已签到并进行中的条数不足10条 且不等于0
            if (activeRelationships.size() != 0) {
                offSet = 10 - activeRelationships.size();//7
                pagesize = offSet;
            } else {
                pagesize = 10;
                pageNums = offSet;
            }
            List<ActiveRelationship> activeRelationships1 = activityFeiMapper.queryByUserActiveRelation0(id, pageNums, pagesize);//  3 10 4 6    0 10 4 6
            if (activeRelationships1.size() != pagesize) {   //0 10 10 0   10 10 4 6 0
                offSet = activeRelationships1.size() + pageNums;
            } else {
                offSet = offSet + 10;
            }
            activeRelationships.addAll(activeRelationships1);
        }
        if (CollectionUtils.isEmpty(activeRelationships)) {
            return new PageableDetails();
        }
        //活动id集合
        List<Long> acs = activeRelationships.stream().map(ActiveRelationship::getAcId).collect(Collectors.toList());
        List<ActivityByUser> activityByUsers = activityFeiService.queryByActivityUser(acs);
        //机构id集合
        List<Long> mes = activityByUsers.stream().map(ActivityByUser::getMechanismId).collect(Collectors.toList());
        //查询出来的机构信息
        List<MechanismImgIds> mechanismImgIds = mechanismFeiMapper.queryByMeChanismActiveImg(mes);
        activeRelationships.forEach(activeRelationship -> {
            activityByUsers.forEach(activityByUser -> {
                //如果活动关系id与活动id相同 则说明是一个活动
                if (activeRelationship.getAcId().equals(activityByUser.getId())) {
                    activeRelationship.setName(activityByUser.getName());
                }
                mechanismImgIds.forEach(mechanismImgIds1 -> {
                    //如果机构id与活动机构id相同则说明是该机构发布的活动
                    if (mechanismImgIds1.getId().equals(activityByUser.getMechanismId())) {
                        activeRelationship.setMechanism_img(mechanismImgIds1.getPicture());
                    }
                });
            });
        });
        return returnPageable(pageNumber, pageSize, count, offSet, activeRelationships);
    }

    /**
     * 查询用户活动-历史
     *
     * @param id
     * @param pageable
     * @return
     */
    @Override
    public PageableDetails queryUserActivityHistory(Long id, Long offSets, Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        int offSet = Math.toIntExact(offSets);
        //总条数
        Integer count = activityFeiMapper.countUserActivityRelationshipHistory(id);
        if (count == 0) {
            return null;
        }
        //查询史历且签到的所有数据
        List<ActiveRelationship> activeRelationships = activityFeiMapper.queryByUserActiveRelationHistory1(id, pageNumber * pageSize, pageSize);
        if (CollectionUtils.isEmpty(activeRelationships) || activeRelationships.size() < 10) {
            int pageNums = 0;
            int pagesize = 0;
            //若已签到并进行中的条数不足10条 且不等于0
            if (activeRelationships.size() != 0) {
                offSet = 10 - activeRelationships.size();//7
                pagesize = offSet;
            } else {
                pagesize = 10;
                pageNums = offSet;
            }
            List<ActiveRelationship> activeRelationships1 = activityFeiMapper.queryByUserActiveRelationHistory0(id, pageNums, pagesize);
            if (activeRelationships1.size() != pagesize) {   //0 10 10 0   10 10 4 6 0
                offSet = activeRelationships1.size() + pageNums;
            } else {
                offSet = offSet + 10;
            }
            activeRelationships.addAll(activeRelationships1);
        }
        if (CollectionUtils.isEmpty(activeRelationships)) {
            return new PageableDetails();
        }
        //活动id集合
        List<Long> acs = activeRelationships.stream().map(ActiveRelationship::getAcId).collect(Collectors.toList());
        List<ActivityByUser> activityByUsers = activityFeiService.queryByActivityUser(acs);
        List<Long> mes = activityByUsers.stream().map(ActivityByUser::getMechanismId).collect(Collectors.toList());
        List<MechanismImgIds> mechanismImgIds = mechanismFeiMapper.queryByMeChanismActiveImg(mes);
        activeRelationships.forEach(activeRelationship -> {
            activityByUsers.forEach(activityByUser -> {
                //如果活动关系id与活动id相同 则说明是一个活动
                if (activeRelationship.getAcId().equals(activityByUser.getId())) {
                    activeRelationship.setName(activityByUser.getName());
                }
                mechanismImgIds.forEach(mechanismImgIds1 -> {
                    //如果机构id与活动机构id相同则说明是该机构发布的活动
                    if (mechanismImgIds1.getId().equals(activityByUser.getMechanismId())) {
                        activeRelationship.setMechanism_img(mechanismImgIds1.getPicture());
                    }
                });
            });
        });
        return returnPageable(pageNumber, pageSize, count, offSet, activeRelationships);
    }

    /**
     * 查询用户-领养相关信息
     *
     * @param mes
     * @return
     */
    @Override
    public List<Mechanism> queryByUserAdoption(List<Long> mes) {
        return mechanismFeiMapper.queryByUserAdoption(mes);
    }

    /**
     * 查询用户关联机构id
     *
     * @param id
     * @return
     */
    @Override
    public Long queryById(Long id) {
        Long aLong = mechanismFeiMapper.queryById(id);
        //该用户没有关联机构
        if (aLong == null) {
            return -1L;
        }
        return aLong;
    }

    /**
     * 根据id查询机构简单信息
     *
     * @param meId
     * @return
     */
    @Override
    public Mechanism queryByMechanismId(Long meId) {
        return mechanismFeiMapper.queryByMeSimiple(meId);
    }

    /**
     * 查看申请成为机构的用户及信息列表
     *
     * @param pageable
     * @return
     */
    @Override
    public PageableDetails queryMechanismApply(Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        List<User> users = userFeiController.queryRole3Ids();
        if (CollectionUtils.isEmpty(users)) {
            ExceptionUtils.error(CommonCode.DATA_ERROR);
        }
        List<Long> ids = users.stream().map(User::getId).collect(Collectors.toList());
        Integer total = users.size();
        List<Mechanism> mechanismList = mechanismFeiMapper.queryBy3MechanismApply(ids, pageNumber * pageSize, pageSize);
        List<MechanismApply> mechanismApplies = new ArrayList<>();
        mechanismList.forEach(mechanism -> {
            MechanismApply mechanismApply = new MechanismApply();
            users.forEach(user -> {
                if (mechanism.getUserId().equals(user.getId())) {
                    mechanismApply.setUser(user);
                    mechanismApply.setMechanism(mechanism);
                }
            });
            mechanismApplies.add(mechanismApply);
        });
        //总页数
        int totalPages = PageUtils.returnPages(total, pageSize);
        return new PageableDetails<>(pageNumber, pageSize, total, totalPages, mechanismApplies);
    }

    /**
     * 通过
     *
     * @param id
     */
    @Override
    @Transactional
    public void success(Long id) {
        Mechanism mechanism = mechanismFeiMapper.queryByIdExistence(id);
        if (mechanism == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        mechanismFeiMapper.updatePower(id);
        RoleUser roleUser = new RoleUser();
        roleUser.setId(mechanism.getUserId());
        roleUser.setRole(3);
        userFeiController.update_role(roleUser);
        createRq(mechanism.getId(), "机构");
        // 删除被通过用户在redis中的用户详情
        userFeiController.removeUserDetails(mechanism.getUserId());
        // 异步修改该用户原本所有数据的me_id为机构id
        taskTool.updateAllDataMeId(mechanism.getUserId(), id);
    }

    /**
     * 不通过
     *
     * @param id
     */
    @Override
    @Transactional
    public void error(Long id) {
        Mechanism mechanism = mechanismFeiMapper.queryByIdExistence(id);
        if (mechanism == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }

        mechanismFeiMapper.delete(id);
        RoleUser roleUser = new RoleUser();
        roleUser.setId(mechanism.getUserId());
        roleUser.setRole(1);
        userFeiController.update_role(roleUser);
        imgFeiServer.delete(mechanism.getPicture());

    }

    /**
     * 修改机构数据
     *
     * @param mechanismDataUp
     */
    @Override
    @Transactional
    public void upMechanismData(MechanismDataUp mechanismDataUp) {

        if (mechanismDataUp.getInOrDe()) {
            mechanismDataMapper.updateIn(mechanismDataUp);
        } else {
            mechanismDataMapper.updateDe(mechanismDataUp);
        }
    }

    /**
     * 查询用户是否是义工以及义工信息
     * @param us_id
     * @return
     */
    @Override
    public List<VolunteerUser> queryVolunteer(Long us_id) {
        List<VolunteerUser> volunteerUsers = volunteerMapper.queryVolunTeerS(us_id);
        if(CollectionUtils.isEmpty(volunteerUsers)){
            return new ArrayList<>();
        }
        List<Long> collect = volunteerUsers.stream().map(VolunteerUser::getMeId).collect(Collectors.toList());
        List<Mechanism> mechanismList = mechanismFeiMapper.queryByMechanism(collect);
        volunteerUsers.forEach(volunteerUser -> {
            mechanismList.forEach(mechanism -> {
                if (mechanism.getId().equals(volunteerUser.getMeId())){
                    volunteerUser.setMeName(mechanism.getName());
                    volunteerUser.setPicture(mechanism.getPicture());
                }
            });
        });
        return volunteerUsers;
    }

    /**
     * 查询机构关于收容转领养方面的信息
     * @param me_id
     * @return
     */
    @Override
    public Mechanism queryByMechanismAsylum(Long me_id) {
        return  mechanismFeiMapper.queryByMechanismByAsylum(me_id);
    }


    /**
     * 返回
     *
     * @param pageNumber 当前页
     * @param pageSize   每页条数
     * @param count      总条数
     * @param list       返回数据
     * @param <T>        泛型
     * @return
     */
    public <T> PageableDetails returnPageable(int pageNumber, Integer pageSize, Integer count, Integer offSet, List<T> list) {
        //总页数
        int totalPages = PageUtils.returnPages(count, pageSize);
        return new PageableDetails<>(pageNumber, pageSize, count, totalPages, offSet, list);
    }

    /**
     * 创建机构邀请义工二维码
     *
     * @param meId
     * @return
     */
    @Transactional
    public void createRq(Long meId, String text) {
        RqCode rqCode = imgFeiServer.queryRqCodeMe(meId);
        if (rqCode.getId() == null) {
            rqCode = new RqCode();
            rqCode.setMeId(meId);
            //生成二维码
            try {
                String url = RQUrl + meId + ".jpg";
                rqCode.setPath(url);
                RqUtils.encode(text,  null,url, true);
            } catch (Exception e) {
                log.error("生成二维码失败");
                e.printStackTrace();
            }
            String s = imgFeiServer.saveRqCodeMe(rqCode);
            rqCode.setPath(s);
        }else {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
    }

}
